/*
 * Copyright (C) 2012 Jesse Webb (gweebz@gmail.com)
 *
 * This file is part of Gwahtzee.
 *
 * Gwahtzee is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Gwahtzee is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Gwahtzee.  If not, see <http://www.gnu.org/licenses/>.
 */

package com.googlecode.gwahtzee.gui.playgame;

import com.googlecode.gwahtzee.model.Dice;
import com.googlecode.gwahtzee.model.Die;
import com.googlecode.gwahtzee.model.ScoreSheet;
import org.newdawn.slick.*;
import org.newdawn.slick.state.BasicGameState;
import org.newdawn.slick.state.StateBasedGame;

import java.util.ArrayList;
import java.util.List;

public class PlayGameState extends BasicGameState {

    private static final int PXL_DICE_LEFT_MARGIN = 140;
    private static final int PXL_DICE_TOP_MARGIN = 400;
    private static final int PXL_DIE_FACE_IMAGE_LENGTH = 111;
    private static final int PXL_DIE_SEPARATOR = 40;

    private Image backgroundImage;
    private ScoreSheetGraphic scoreSheetGraphic;
    private ScoreSheet.Cell cellThatMouseIsOver;
    private Image playSurfaceImage;

    private Dice dice;
    private List<Image> dieFaceImages;
    private int[] dieXs;
    private int dieY;

    private int stateId;

    public PlayGameState(int stateId) {
        this.stateId = stateId;
    }

    @Override
    public int getID() {
        return stateId;
    }

    @Override
    public void init(GameContainer gameContainer, StateBasedGame stateBasedGame) throws SlickException {
        backgroundImage = new Image("images/background.png");

        scoreSheetGraphic = new ScoreSheetGraphic(140, 30, new Image("images/score-sheet.png"));

        playSurfaceImage = new Image("images/play-surface.png");

        dice = new Dice();
        dieFaceImages = splitSubImagesFromDieFacesImage(new Image("images/die-faces.png"));
        dieXs = buildArrayOfDieXPositions();
        dieY = PXL_DICE_TOP_MARGIN;
    }

    @Override
    public void update(GameContainer gameContainer, StateBasedGame stateBasedGame, int delta) throws SlickException {
        Input input = gameContainer.getInput();
        int mouseX = input.getMouseX();
        int mouseY = input.getMouseY();

        if (input.isKeyPressed(Input.KEY_ESCAPE)) gameContainer.exit();

        scoreSheetGraphic.update();

        if (input.isMousePressed(Input.MOUSE_LEFT_BUTTON)) {
            for (int i = 0; i < dice.size(); i++) {
                int dieX = dieXs[i];
                if (mouseX >= dieX && mouseX <= dieX + PXL_DIE_FACE_IMAGE_LENGTH &&
                        mouseY >= dieY && mouseY <= dieY + PXL_DIE_FACE_IMAGE_LENGTH) {
                    // mouse clicked on die
                    Die die = dice.get(i);
                    die.roll();
                }
            }
        }

        cellThatMouseIsOver = null;
        for (ScoreSheet.Cell cell : ScoreSheet.Cells) {
            if (scoreSheetGraphic.isMouseOverCell(mouseX, mouseY, cell)) {
                cellThatMouseIsOver = cell;
            }
        }
    }

    @Override
    public void render(GameContainer gameContainer, StateBasedGame stateBasedGame, Graphics graphics) throws SlickException {
        backgroundImage.draw(0, 0);
        scoreSheetGraphic.render();
        playSurfaceImage.draw(0, 360);

        for (int i = 0; i < dice.size(); i++) {
            Die die = dice.get(i);
            Image dieFaceImage = dieFaceImages.get(die.getFaceValue() - 1);
            dieFaceImage.draw(dieXs[i], dieY);
        }

        if (cellThatMouseIsOver != null) {
            scoreSheetGraphic.renderHighlightedCell(graphics, cellThatMouseIsOver);
        }
    }

    private List<Image> splitSubImagesFromDieFacesImage(Image dieFacesImage) {
        List<Image> subImages = new ArrayList<Image>();
        int x = 0;
        int y = 0;
        for (int i = 0; i < Die.NUM_SIDES; i++) {
            subImages.add(dieFacesImage.getSubImage(x, y, PXL_DIE_FACE_IMAGE_LENGTH, PXL_DIE_FACE_IMAGE_LENGTH));
            x += PXL_DIE_FACE_IMAGE_LENGTH;
        }
        return subImages;
    }

    private int[] buildArrayOfDieXPositions() {
        int[] dieXs = new int[dice.size()];
        int x = PXL_DICE_LEFT_MARGIN;
        for (int i = 0; i < dice.size(); i++) {
            dieXs[i] = x;
            x += PXL_DIE_FACE_IMAGE_LENGTH + PXL_DIE_SEPARATOR;
        }
        return dieXs;
    }
}
